[[aop-proxying]]
= Proxying Mechanisms

Spring AOP uses either JDK dynamic proxies or CGLIB to create the proxy for a given
target object. JDK dynamic proxies are built into the JDK, whereas CGLIB is a common
open-source class definition library (repackaged into `spring-core`).

If the target object to be proxied implements at least one interface, a JDK dynamic
proxy is used. All of the interfaces implemented by the target type are proxied.
If the target object does not implement any interfaces, a CGLIB proxy is created.

If you want to force the use of CGLIB proxying (for example, to proxy every method
defined for the target object, not only those implemented by its interfaces),
you can do so. However, you should consider the following issues:

* With CGLIB, `final` methods cannot be advised, as they cannot be overridden in
  runtime-generated subclasses.
* As of Spring 4.0, the constructor of your proxied object is NOT called twice anymore,
  since the CGLIB proxy instance is created through Objenesis. Only if your JVM does
  not allow for constructor bypassing, you might see double invocations and
  corresponding debug log entries from Spring's AOP support.
* Your CGLIB proxy usage may face limitations with the JDK 9+ platform module system.
  As a typical case, you cannot create a CGLIB proxy for a class from the `java.lang`
  package when deploying on the module path. Such cases require a JVM bootstrap flag
  `--add-opens=java.base/java.lang=ALL-UNNAMED` which is not available for modules.

To force the use of CGLIB proxies, set the value of the `proxy-target-class` attribute
of the `<aop:config>` element to true, as follows:

[source,xml,indent=0,subs="verbatim"]
----
	<aop:config proxy-target-class="true">
		<!-- other beans defined here... -->
	</aop:config>
----

To force CGLIB proxying when you use the @AspectJ auto-proxy support, set the
`proxy-target-class` attribute of the `<aop:aspectj-autoproxy>` element to `true`,
as follows:

[source,xml,indent=0,subs="verbatim"]
----
	<aop:aspectj-autoproxy proxy-target-class="true"/>
----

[NOTE]
====
Multiple `<aop:config/>` sections are collapsed into a single unified auto-proxy creator
at runtime, which applies the _strongest_ proxy settings that any of the
`<aop:config/>` sections (typically from different XML bean definition files) specified.
This also applies to the `<tx:annotation-driven/>` and `<aop:aspectj-autoproxy/>`
elements.

To be clear, using `proxy-target-class="true"` on `<tx:annotation-driven/>`,
`<aop:aspectj-autoproxy/>`, or `<aop:config/>` elements forces the use of CGLIB
proxies _for all three of them_.
====



[[aop-understanding-aop-proxies]]
== Understanding AOP Proxies

Spring AOP is proxy-based. It is vitally important that you grasp the semantics of
what that last statement actually means before you write your own aspects or use any of
the Spring AOP-based aspects supplied with the Spring Framework.

Consider first the scenario where you have a plain-vanilla, un-proxied,
nothing-special-about-it, straight object reference, as the following
code snippet shows:

[tabs]
======
Java::
+
[source,java,indent=0,subs="verbatim",role="primary"]
----
	public class SimplePojo implements Pojo {

		public void foo() {
			// this next method invocation is a direct call on the 'this' reference
			this.bar();
		}

		public void bar() {
			// some logic...
		}
	}
----

Kotlin::
+
[source,kotlin,indent=0,subs="verbatim",role="secondary"]
----
	class SimplePojo : Pojo {

		fun foo() {
			// this next method invocation is a direct call on the 'this' reference
			this.bar()
		}

		fun bar() {
			// some logic...
		}
	}
----
======

If you invoke a method on an object reference, the method is invoked directly on
that object reference, as the following image and listing show:

image::aop-proxy-plain-pojo-call.png[]

[tabs]
======
Java::
+
[source,java,indent=0,subs="verbatim",role="primary"]
----
	public class Main {

		public static void main(String[] args) {
			Pojo pojo = new SimplePojo();
			// this is a direct method call on the 'pojo' reference
			pojo.foo();
		}
	}
----

Kotlin::
+
[source,kotlin,indent=0,subs="verbatim",role="secondary"]
----
	fun main() {
		val pojo = SimplePojo()
		// this is a direct method call on the 'pojo' reference
		pojo.foo()
	}
----
======

Things change slightly when the reference that client code has is a proxy. Consider the
following diagram and code snippet:

image::aop-proxy-call.png[]

[tabs]
======
Java::
+
[source,java,indent=0,subs="verbatim",role="primary"]
----
	public class Main {

		public static void main(String[] args) {
			ProxyFactory factory = new ProxyFactory(new SimplePojo());
			factory.addInterface(Pojo.class);
			factory.addAdvice(new RetryAdvice());

			Pojo pojo = (Pojo) factory.getProxy();
			// this is a method call on the proxy!
			pojo.foo();
		}
	}
----

Kotlin::
+
[source,kotlin,indent=0,subs="verbatim",role="secondary"]
----
fun main() {
	val factory = ProxyFactory(SimplePojo())
	factory.addInterface(Pojo::class.java)
	factory.addAdvice(RetryAdvice())

	val pojo = factory.proxy as Pojo
	// this is a method call on the proxy!
	pojo.foo()
}
----
======

The key thing to understand here is that the client code inside the `main(..)` method
of the `Main` class has a reference to the proxy. This means that method calls on that
object reference are calls on the proxy. As a result, the proxy can delegate to all of
the interceptors (advice) that are relevant to that particular method call. However,
once the call has finally reached the target object (the `SimplePojo` reference in
this case), any method calls that it may make on itself, such as `this.bar()` or
`this.foo()`, are going to be invoked against the `this` reference, and not the proxy.
This has important implications. It means that self-invocation is not going to result
in the advice associated with a method invocation getting a chance to run.

Okay, so what is to be done about this? The best approach (the term "best" is used
loosely here) is to refactor your code such that the self-invocation does not happen.
This does entail some work on your part, but it is the best, least-invasive approach.
The next approach is absolutely horrendous, and we hesitate to point it out, precisely
because it is so horrendous. You can (painful as it is to us) totally tie the logic
within your class to Spring AOP, as the following example shows:

[tabs]
======
Java::
+
[source,java,indent=0,subs="verbatim",role="primary"]
----
	public class SimplePojo implements Pojo {

		public void foo() {
			// this works, but... gah!
			((Pojo) AopContext.currentProxy()).bar();
		}

		public void bar() {
			// some logic...
		}
	}
----

Kotlin::
+
[source,kotlin,indent=0,subs="verbatim",role="secondary"]
----
	class SimplePojo : Pojo {

		fun foo() {
			// this works, but... gah!
			(AopContext.currentProxy() as Pojo).bar()
		}

		fun bar() {
			// some logic...
		}
	}
----
======

This totally couples your code to Spring AOP, and it makes the class itself aware of
the fact that it is being used in an AOP context, which flies in the face of AOP. It
also requires some additional configuration when the proxy is being created, as the
following example shows:

[tabs]
======
Java::
+
[source,java,indent=0,subs="verbatim",role="primary"]
----
	public class Main {

		public static void main(String[] args) {
			ProxyFactory factory = new ProxyFactory(new SimplePojo());
			factory.addInterface(Pojo.class);
			factory.addAdvice(new RetryAdvice());
			factory.setExposeProxy(true);

			Pojo pojo = (Pojo) factory.getProxy();
			// this is a method call on the proxy!
			pojo.foo();
		}
	}
----

Kotlin::
+
[source,kotlin,indent=0,subs="verbatim",role="secondary"]
----
	fun main() {
		val factory = ProxyFactory(SimplePojo())
		factory.addInterface(Pojo::class.java)
		factory.addAdvice(RetryAdvice())
		factory.isExposeProxy = true

		val pojo = factory.proxy as Pojo
		// this is a method call on the proxy!
		pojo.foo()
	}
----
======

Finally, it must be noted that AspectJ does not have this self-invocation issue because
it is not a proxy-based AOP framework.




